package com.alan.shiro.api.token.manager.impl;

import com.alan.shiro.api.token.StatelessToken;
import com.alan.shiro.api.token.manager.AbstractTokenManager;
import com.alan.shiro.api.token.manager.TokenManager;
import com.alan.shiro.api.utils.JwtTokenUtils;
import com.alibaba.fastjson.JSON;
import com.nimbusds.jose.JOSEException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 使用Jwt实现token的发放和验证
 * @Auther: Alan liu
 * @Date: 2018/12/14 15:53
 * @Description: RaFilterJwtTokenManagerImpl
 */
@Slf4j
public class RaFilterJwtTokenManagerImpl extends AbstractTokenManager {

    @Setter
    @Getter
    private String key;

    /**
     * 失效时间 单位秒
     */
    @Setter
    @Getter
    private long expirateTime;


    @Override
    public StatelessToken createToken(String userCode) throws Exception {
       String token = createStringToken(userCode);
        StatelessToken tokenModel = new StatelessToken(Long.valueOf(userCode), token);
        return tokenModel;
    }

    @Override
    public String createStringToken(String userCode) throws JOSEException {
        //获取生成token
        Map<String, Object> map = new HashMap<>();
        //建立载荷，这些数据根据业务，自己定义。
        map.put("uid", userCode);
        //生成时间
        map.put("sta", System.currentTimeMillis());
        //过期时间
        map.put("exp", System.currentTimeMillis()+(expirateTime * 1000));
        String token = JwtTokenUtils.creatToken(map,key);
        return token;
    }

    @Override
    public boolean checkToken(StatelessToken statelessToken) {
        String token = (String) statelessToken.getCredentials();
        return checkToken(token);
    }

    @Override
    public boolean check(String authentication) {
        StatelessToken token = getToken(authentication);
        if(token == null){
            return false;
        }
        return checkToken(token);
    }

    private boolean checkToken(String token){
        Map<String, Object> validMap = null;
        try {
            validMap = JwtTokenUtils.valid(token,key);
            int i = (int) validMap.get("Result");
            if (i == 0) {
                log.info("token解析成功");
                net.minidev.json.JSONObject jsonObject = (net.minidev.json.JSONObject) validMap.get("data");
                log.info("uid是" + jsonObject.get("uid"));
                log.info("sta是"+jsonObject.get("sta"));
                log.info("exp是"+jsonObject.get("exp"));
                return true;
            } else if (i == 2) {
                log.info("token已经过期");
                return false;
            }
            log.info("解析结果不对：{}", JSON.toJSONString(validMap));
            return false;
        } catch (Exception e) {
            log.error("token 验证异常：{}",e);
            return false;
        }
    }

    @Override
    public void deleteToken(String userCode) {

    }

}
